﻿var SWFUpload = function (settings) {
	this.initSWFUpload(settings);
};

SWFUpload.prototype.initSWFUpload = function (settings) {
	try {
		this.customSettings = {};	
		this.settings = settings;
		this.eventQueue = [];
		this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
		this.movieElement = null;

		
		SWFUpload.instances[this.movieName] = this;

		
		this.initSettings();
		this.loadFlash();
		this.displayDebugInfo();
	} catch (ex) {
		delete SWFUpload.instances[this.movieName];
		throw ex;
	}
};




SWFUpload.instances = {};
SWFUpload.movieCount = 0;
SWFUpload.version = "2.1.0";
SWFUpload.QUEUE_ERROR = {
	QUEUE_LIMIT_EXCEEDED	  		: -100,
	FILE_EXCEEDS_SIZE_LIMIT  		: -110,
	ZERO_BYTE_FILE			  		: -120,
	INVALID_FILETYPE		  		: -130
};
SWFUpload.UPLOAD_ERROR = {
	HTTP_ERROR				  		: -200,
	MISSING_UPLOAD_URL	      		: -210,
	IO_ERROR				  		: -220,
	SECURITY_ERROR			  		: -230,
	UPLOAD_LIMIT_EXCEEDED	  		: -240,
	UPLOAD_FAILED			  		: -250,
	SPECIFIED_FILE_ID_NOT_FOUND		: -260,
	FILE_VALIDATION_FAILED	  		: -270,
	FILE_CANCELLED			  		: -280,
	UPLOAD_STOPPED					: -290
};
SWFUpload.FILE_STATUS = {
	QUEUED		 : -1,
	IN_PROGRESS	 : -2,
	ERROR		 : -3,
	COMPLETE	 : -4,
	CANCELLED	 : -5
};








SWFUpload.prototype.initSettings = function () {
	this.ensureDefault = function (settingName, defaultValue) {
		this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
	};
	
	
	this.ensureDefault("upload_url", "");
	this.ensureDefault("file_post_name", "Filedata");
	this.ensureDefault("post_params", {});
	this.ensureDefault("use_query_string", false);
	this.ensureDefault("requeue_on_error", false);
	
	
	this.ensureDefault("file_types", "*.*");
	this.ensureDefault("file_types_description", "All Files");
	this.ensureDefault("file_size_limit", 0);	
	this.ensureDefault("file_upload_limit", 0);
	this.ensureDefault("file_queue_limit", 0);

	
	this.ensureDefault(" ", "swfupload_f9.swf");
	this.ensureDefault("flash_color", "#FFFFFF");

	
	this.ensureDefault("debug", false);
	this.settings.debug_enabled = this.settings.debug;	
	
	
	this.settings.return_upload_start_handler = this.returnUploadStart;
	this.ensureDefault("swfupload_loaded_handler", null);
	this.ensureDefault("file_dialog_start_handler", null);
	this.ensureDefault("file_queued_handler", null);
	this.ensureDefault("file_queue_error_handler", null);
	this.ensureDefault("file_dialog_complete_handler", null);
	
	this.ensureDefault("upload_start_handler", null);
	this.ensureDefault("upload_progress_handler", null);
	this.ensureDefault("upload_error_handler", null);
	this.ensureDefault("upload_success_handler", null);
	this.ensureDefault("upload_complete_handler", null);
	
	this.ensureDefault("debug_handler", this.debugMessage);

	this.ensureDefault("custom_settings", {});

	
	this.customSettings = this.settings.custom_settings;
	
	delete this.ensureDefault;
};



SWFUpload.prototype.loadFlash = function () {
	var targetElement, container;

	
	if (document.getElementById(this.movieName) !== null) {
		throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
	}

	
	targetElement = document.getElementsByTagName("body")[0];

	if (targetElement == undefined) {
		throw "Could not find the 'body' element.";
	}

	
	container = document.createElement("div");
	container.style.width = "1px";
	container.style.height = "1px";

	targetElement.appendChild(container);
	container.innerHTML = this.getFlashHTML();	
};


SWFUpload.prototype.getFlashHTML = function () {
	
	return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="1" height="1" style="-moz-user-focus: ignore;">',
				'<param name="movie" value="', this.settings.flash_url, '" />',
				'<param name="bgcolor" value="', this.settings.flash_color, '" />',
				'<param name="quality" value="high" />',
				'<param name="menu" value="false" />',
				'<param name="allowScriptAccess" value="always" />',
				'<param name="flashvars" value="' + this.getFlashVars() + '" />',
				'</object>'].join("");
};



SWFUpload.prototype.getFlashVars = function () {
	
	var paramString = this.buildParamString();

	
	return ["movieName=", encodeURIComponent(this.movieName),
			"&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
			"&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
			"&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
			"&amp;params=", encodeURIComponent(paramString),
			"&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
			"&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
			"&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
			"&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
			"&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
			"&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
			"&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled)].join("");
};



SWFUpload.prototype.getMovieElement = function () {
	if (this.movieElement == undefined) {
		this.movieElement = document.getElementById(this.movieName);
	}

	if (this.movieElement === null) {
		throw "Could not find Flash element";
	}
	
	return this.movieElement;
};



SWFUpload.prototype.buildParamString = function () {
	var postParams = this.settings.post_params;
	var paramStringPairs = [];

	if (typeof(postParams) === "object") {
		for (var name in postParams) {
			if (postParams.hasOwnProperty(name)) {
				paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
			}
		}
	}

	return paramStringPairs.join("&amp;");
};




SWFUpload.prototype.destroy = function () {
	try {
		
		this.stopUpload();
		
		
		var movieElement = null;
		try {
			movieElement = this.getMovieElement();
		} catch (ex) {
		}
		
		if (movieElement != undefined && movieElement.parentNode != undefined && typeof(movieElement.parentNode.removeChild) === "function") {
			var container = movieElement.parentNode;
			if (container != undefined) {
				container.removeChild(movieElement);
				if (container.parentNode != undefined && typeof(container.parentNode.removeChild) === "function") {
					container.parentNode.removeChild(container);
				}
			}
		}
		
		
		SWFUpload.instances[this.movieName] = null;
		delete SWFUpload.instances[this.movieName];

		delete this.movieElement;
		delete this.settings;
		delete this.customSettings;
		delete this.eventQueue;
		delete this.movieName;
		
		return true;
	} catch (ex1) {
		return false;
	}
};





SWFUpload.prototype.displayDebugInfo = function () {
	this.debug(
		[
			"---SWFUpload Instance Info---\n",
			"Version: ", SWFUpload.version, "\n",
			"Movie Name: ", this.movieName, "\n",
			"Settings:\n",
			"\t", "upload_url:             ", this.settings.upload_url, "\n",
			"\t", "use_query_string:       ", this.settings.use_query_string.toString(), "\n",
			"\t", "file_post_name:         ", this.settings.file_post_name, "\n",
			"\t", "post_params:            ", this.settings.post_params.toString(), "\n",
			"\t", "file_types:             ", this.settings.file_types, "\n",
			"\t", "file_types_description: ", this.settings.file_types_description, "\n",
			"\t", "file_size_limit:        ", this.settings.file_size_limit, "\n",
			"\t", "file_upload_limit:      ", this.settings.file_upload_limit, "\n",
			"\t", "file_queue_limit:       ", this.settings.file_queue_limit, "\n",
			"\t", "flash_url:              ", this.settings.flash_url, "\n",
			"\t", "flash_color:            ", this.settings.flash_color, "\n",
			"\t", "debug:                  ", this.settings.debug.toString(), "\n",
			"\t", "custom_settings:        ", this.settings.custom_settings.toString(), "\n",
			"Event Handlers:\n",
			"\t", "swfupload_loaded_handler assigned:  ", (typeof(this.settings.swfupload_loaded_handler) === "function").toString(), "\n",
			"\t", "file_dialog_start_handler assigned: ", (typeof(this.settings.file_dialog_start_handler) === "function").toString(), "\n",
			"\t", "file_queued_handler assigned:       ", (typeof(this.settings.file_queued_handler) === "function").toString(), "\n",
			"\t", "file_queue_error_handler assigned:  ", (typeof(this.settings.file_queue_error_handler) === "function").toString(), "\n",
			"\t", "upload_start_handler assigned:      ", (typeof(this.settings.upload_start_handler) === "function").toString(), "\n",
			"\t", "upload_progress_handler assigned:   ", (typeof(this.settings.upload_progress_handler) === "function").toString(), "\n",
			"\t", "upload_error_handler assigned:      ", (typeof(this.settings.upload_error_handler) === "function").toString(), "\n",
			"\t", "upload_success_handler assigned:    ", (typeof(this.settings.upload_success_handler) === "function").toString(), "\n",
			"\t", "upload_complete_handler assigned:   ", (typeof(this.settings.upload_complete_handler) === "function").toString(), "\n",
			"\t", "debug_handler assigned:             ", (typeof(this.settings.debug_handler) === "function").toString(), "\n"
		].join("")
	);
};

/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
	the maintain v2 API compatibility
*/

SWFUpload.prototype.addSetting = function (name, value, default_value) {
    if (value == undefined) {
        return (this.settings[name] = default_value);
    } else {
        return (this.settings[name] = value);
	}
};


SWFUpload.prototype.getSetting = function (name) {
    if (this.settings[name] != undefined) {
        return this.settings[name];
	}

    return "";
};






SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
	argumentArray = argumentArray || [];
	
	var self = this;
	var callFunction = function () {
		var movieElement = self.getMovieElement();
		var returnValue;
		if (typeof(movieElement[functionName]) === "function") {
			
			if (argumentArray.length === 0) {
				returnValue = movieElement[functionName]();
			} else if (argumentArray.length === 1) {
				returnValue = movieElement[functionName](argumentArray[0]);
			} else if (argumentArray.length === 2) {
				returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]);
			} else if (argumentArray.length === 3) {
				returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]);
			} else {
				throw "Too many arguments";
			}
			
			
			if (returnValue != undefined && typeof(returnValue.post) === "object") {
				returnValue = self.unescapeFilePostParams(returnValue);
			}
			
			return returnValue;
		} else {
			throw "Invalid function name";
		}
	};
	
	return callFunction();
};


/* *****************************
	-- Flash control methods --
	Your UI should use these
	to operate SWFUpload
   ***************************** */



SWFUpload.prototype.selectFile = function () {
	this.callFlash("SelectFile");
};






SWFUpload.prototype.selectFiles = function () {
	this.callFlash("SelectFiles");
};




SWFUpload.prototype.startUpload = function (fileID) {
	this.callFlash("StartUpload", [fileID]);
};




SWFUpload.prototype.cancelUpload = function (fileID) {
	this.callFlash("CancelUpload", [fileID]);
};



SWFUpload.prototype.stopUpload = function () {
	this.callFlash("StopUpload");
};

/* ************************
 * Settings methods
 *   These methods change the SWFUpload settings.
 *   SWFUpload settings should not be changed directly on the settings object
 *   since many of the settings need to be passed to Flash in order to take
 *   effect.
 * *********************** */


SWFUpload.prototype.getStats = function () {
	return this.callFlash("GetStats");
};





SWFUpload.prototype.setStats = function (statsObject) {
	this.callFlash("SetStats", [statsObject]);
};



SWFUpload.prototype.getFile = function (fileID) {
	if (typeof(fileID) === "number") {
		return this.callFlash("GetFileByIndex", [fileID]);
	} else {
		return this.callFlash("GetFile", [fileID]);
	}
};




SWFUpload.prototype.addFileParam = function (fileID, name, value) {
	return this.callFlash("AddFileParam", [fileID, name, value]);
};



SWFUpload.prototype.removeFileParam = function (fileID, name) {
	this.callFlash("RemoveFileParam", [fileID, name]);
};


SWFUpload.prototype.setUploadURL = function (url) {
	this.settings.upload_url = url.toString();
	this.callFlash("SetUploadURL", [url]);
};


SWFUpload.prototype.setPostParams = function (paramsObject) {
	this.settings.post_params = paramsObject;
	this.callFlash("SetPostParams", [paramsObject]);
};


SWFUpload.prototype.addPostParam = function (name, value) {
	this.settings.post_params[name] = value;
	this.callFlash("SetPostParams", [this.settings.post_params]);
};


SWFUpload.prototype.removePostParam = function (name) {
	delete this.settings.post_params[name];
	this.callFlash("SetPostParams", [this.settings.post_params]);
};


SWFUpload.prototype.setFileTypes = function (types, description) {
	this.settings.file_types = types;
	this.settings.file_types_description = description;
	this.callFlash("SetFileTypes", [types, description]);
};


SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
	this.settings.file_size_limit = fileSizeLimit;
	this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
};


SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
	this.settings.file_upload_limit = fileUploadLimit;
	this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
};


SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
	this.settings.file_queue_limit = fileQueueLimit;
	this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
};


SWFUpload.prototype.setFilePostName = function (filePostName) {
	this.settings.file_post_name = filePostName;
	this.callFlash("SetFilePostName", [filePostName]);
};


SWFUpload.prototype.setUseQueryString = function (useQueryString) {
	this.settings.use_query_string = useQueryString;
	this.callFlash("SetUseQueryString", [useQueryString]);
};


SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
	this.settings.requeue_on_error = requeueOnError;
	this.callFlash("SetRequeueOnError", [requeueOnError]);
};


SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
	this.settings.debug_enabled = debugEnabled;
	this.callFlash("SetDebugEnabled", [debugEnabled]);
};


/* *******************************
	Flash Event Interfaces
	These functions are used by Flash to trigger the various
	events.
	
	All these functions a Private.
	
	Because the ExternalInterface library is buggy the event calls
	are added to a queue and the queue then executed by a setTimeout.
	This ensures that events are executed in a determinate order and that
	the ExternalInterface bugs are avoided.
******************************* */

SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
	
	
	if (argumentArray == undefined) {
		argumentArray = [];
	} else if (!(argumentArray instanceof Array)) {
		argumentArray = [argumentArray];
	}
	
	var self = this;
	if (typeof(this.settings[handlerName]) === "function") {
		
		this.eventQueue.push(function () {
			this.settings[handlerName].apply(this, argumentArray);
		});
		
		
		setTimeout(function () {
			self.executeNextEvent();
		}, 0);
		
	} else if (this.settings[handlerName] !== null) {
		throw "Event handler " + handlerName + " is unknown or is not a function";
	}
};



SWFUpload.prototype.executeNextEvent = function () {
	

	var  f = this.eventQueue ? this.eventQueue.shift() : null;
	if (typeof(f) === "function") {
		f.apply(this);
	}
};




SWFUpload.prototype.unescapeFilePostParams = function (file) {
	var reg = /[$]([0-9a-f]{4})/i;
	var unescapedPost = {};
	var uk;

	if (file != undefined) {
		for (var k in file.post) {
			if (file.post.hasOwnProperty(k)) {
				uk = k;
				var match;
				while ((match = reg.exec(uk)) !== null) {
					uk = uk.replace(match[0], String.fromCharCode(parseInt("0x"+match[1], 16)));
				}
				unescapedPost[uk] = file.post[k];
			}
		}

		file.post = unescapedPost;
	}

	return file;
};

SWFUpload.prototype.flashReady = function () {
	
	var movieElement = this.getMovieElement();
	if (typeof(movieElement.StartUpload) !== "function") {
		throw "ExternalInterface methods failed to initialize.";
	}
	
	this.queueEvent("swfupload_loaded_handler");
};



SWFUpload.prototype.fileDialogStart = function () {
	this.queueEvent("file_dialog_start_handler");
};



SWFUpload.prototype.fileQueued = function (file) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("file_queued_handler", file);
};



SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
};

/* Called after the file dialog has closed and the selected files have been queued.
	You could call startUpload here if you want the queued files to begin uploading immediately. */
SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued) {
	this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued]);
};

SWFUpload.prototype.uploadStart = function (file) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("return_upload_start_handler", file);
};

SWFUpload.prototype.returnUploadStart = function (file) {
	var returnValue;
	if (typeof(this.settings.upload_start_handler) === "function") {
		file = this.unescapeFilePostParams(file);
		returnValue = this.settings.upload_start_handler.call(this, file);
	} else if (this.settings.upload_start_handler != undefined) {
		throw "upload_start_handler must be a function";
	}

	
	
	if (returnValue === undefined) {
		returnValue = true;
	}
	
	returnValue = !!returnValue;
	
	this.callFlash("ReturnUploadStart", [returnValue]);
};



SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
};

SWFUpload.prototype.uploadError = function (file, errorCode, message) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_error_handler", [file, errorCode, message]);
};

SWFUpload.prototype.uploadSuccess = function (file, serverData) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_success_handler", [file, serverData]);
};

SWFUpload.prototype.uploadComplete = function (file) {
	file = this.unescapeFilePostParams(file);
	this.queueEvent("upload_complete_handler", file);
};

/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
   internal debug console.  You can override this event and have messages written where you want. */
SWFUpload.prototype.debug = function (message) {
	this.queueEvent("debug_handler", message);
};


/* **********************************
	Debug Console
	The debug console is a self contained, in page location
	for debug message to be sent.  The Debug Console adds
	itself to the body if necessary.

	The console is automatically scrolled as messages appear.
	
	If you are using your own debug handler or when you deploy to production and
	have debug disabled you can remove these functions to reduce the file size
	and complexity.
********************************** */
   



SWFUpload.prototype.debugMessage = function (message) {
	if (this.settings.debug) {
		var exceptionMessage, exceptionValues = [];

		
		if (typeof(message) === "object" && typeof(message.name) === "string" && typeof(message.message) === "string") {
			for (var key in message) {
				if (message.hasOwnProperty(key)) {
					exceptionValues.push(key + ": " + message[key]);
				}
			}
			exceptionMessage = exceptionValues.join("\n") || "";
			exceptionValues = exceptionMessage.split("\n");
			exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
			SWFUpload.Console.writeLine(exceptionMessage);
		} else {
			SWFUpload.Console.writeLine(message);
		}
	}
};

SWFUpload.Console = {};
SWFUpload.Console.writeLine = function (message) {
	var console, documentForm;

	try {
		console = document.getElementById("SWFUpload_Console");

		if (!console) {
			documentForm = document.createElement("form");
			document.getElementsByTagName("body")[0].appendChild(documentForm);

			console = document.createElement("textarea");
			console.id = "SWFUpload_Console";
			console.style.fontFamily = "monospace";
			console.setAttribute("wrap", "off");
			console.wrap = "off";
			console.style.overflow = "auto";
			console.style.width = "700px";
			console.style.height = "350px";
			console.style.margin = "5px";
			documentForm.appendChild(console);
		}

		console.value += message + "\n";

		console.scrollTop = console.scrollHeight - console.clientHeight;
	} catch (ex) {
		alert("Exception: " + ex.name + " Message: " + ex.message);
	}
};


/* MY OWN MILTIFILE */

	window.multiFiles = [];

	$.fn.multiFile = function (options) {
		return this.each( function () {
			this.mfId  = window.multiFiles.length;
			window.multiFiles.push( new multiFile(this, options) );
		});
	};
	
	multiFile = function (element, options) {
		if (typeof(element) != "object") {
			throw("Callin multifile without input specified"); 
			return false;
		};
		
		this.input = $(element);
		this.count = 0;
		this.files = [];
		
		this.options = {
			maxFiles : 5,
			messager : boxerError,
			allowed : "gif|jpg|png",
			onChange : function () {}
		};
		
		$.extend(this.options, options);
		
		this.options.allowed = "|" + this.options.allowed + "|";
		
		this.error = function(m) {
			this.options.messager.call( this, m );
		};
		
		this.init = function () {
			this.ul = $('<ul class="filesBox"></ul>').insertAfter(element);
			this.input.change( function () {
				window.multiFiles[this.mfId].add(this.value);
			});
			this.input.attr("name", this.input.attr("name") + "[]");
			this.original = this.input.clone( true );
			this.original[0].mfId = this.input[0].mfId;
		};
				
		this.add = function (filename) {
			if ($.browser.msie) {
				var temp = filename.split('\\');
				filename = temp[temp.length-1];
			};
			
			if (!this.check(filename)) { this.input[0].value = ""; return false; }
			
			var li = $('<li class="file"><a class="cancel" href="#"></a>' + filename + '</li>').appendTo(this.ul);
			
			li.find("a.cancel").click( function () {
				var mf =  window.multiFiles[$(this).parents("ul.filesBox").prev()[0].mfId];
				mf.remove(this.listId);
				return false;
			})[0].listId = this.files.length;
			
			this.files.push( { filename: filename, li: li, input: this.input } );			
			
			this.input.hide();
			
			this.input = this.original.clone( true ).insertBefore(this.input);
			this.input[0].mfId = this.original[0].mfId;
			
			this.count++;
			
			if (this.count >= this.options.maxFiles) {
				this.input.attr("disabled", "disabled");
			};						
			
			this.options.onChange.call( this, this.count );
		};
		
		this.check = function (filename) {
			if (filename == "") { return false; }		
			
			var t = filename.split(".");
			var ext = t[t.length-1];
			
			for (var i = 0; i < this.files.length; i++) { 
				if ( (typeof(this.files[i]) != "undefined" ) && (filename == this.files[i].filename) ) { 
					this.error("Такой файл уже есть в очереди");
					return false;
				}
			};
			
			if (this.options.allowed.indexOf("|" + ext + "|") == -1) { 
				this.error("Недопустимое разширение файла");
				return false;
			}
			
			return true;
		};
		
		this.remove = function (id) { 
			if (typeof(this.files[id]) != "object") {
				this.error("Не могу удалить");
				return false; }
			else {
				var f = this.files[id];
				f.li.remove();
				f.input.remove();
				delete this.files[id];
				this.count--;
				
				if (this.count < this.options.maxFiles) {
					this.input.removeAttr("disabled");
				};
							
				this.options.onChange.call( this, this.count );
			};
		};
		
		this.init();
	};
	
/* MULTIFILE END */


(function($) {
Multiuploader = function(options) {
	
	this.uploadStatus = ['В очереди.', 'Загружается.', 'Ошибка.', 'Загружен.'];
	
	this.status = "picking";
	
	this.queue = {};
	this.complete = 0;
	this.total = 0;
	this.uploaded = [];
	
	this.noflash = true;
	
	this.fileQueued = function (file) {
		var alreadyhere = false;
		
		for (var exists in uploader.queue) {
		    if ((uploader.queue[exists].f.name == file.name) && (uploader.queue[exists].f.size == file.size)) { alreadyhere = true; };
		};
		
		if (alreadyhere) {
			uploader.swf.cancelUpload(file.id);
			boxerAlert("Файл " + file.name + " уже есть в очереди");
			return false;
		};
		
		if (uploader.filesBox.find("li").length > 9) {
			uploader.swf.cancelUpload(file.id);
			boxerAlert("В очереди не может быть больше 10 файлов");
			return false;
		};
		
		var size = file.size;
		
		size = (size > 1024) ? ((size > 1048576) ?  Math.round(size/1048576 ) + " Mb" : Math.round(size/1024) + " Kb") : size + " b";
		
		var newli = $('<li id="upl' + file.id + '"><a href="#" class="cancel"></a><div class="status">' + uploader.uploadStatus[file.filestatus+1] + '</div><div class="name">' + file.name + ' <span class="size">(' + size + ')</span></div></li>');
		
		uploader.total = uploader.total + file.size;
			
		newli[0].id = file.id;
		
		uploader.queue[file.id] = {li: newli, f: file};
			
		newli.find("a").click( function () {
			var parent = this.parentNode;
			
			uploader.total = uploader.total - uploader.queue[parent.id].f.size;
			
			delete uploader.queue[parent.id];
			
			uploader.swf.cancelUpload(parent.id);
			$(parent).fadeTo(300, 0.01, function () { $(this).slideUp(300, function () { $(this).remove(); }); } );
			return false;
		});
		
		newli.appendTo(uploader.filesBox).hide().css( { opacity: 0.01 } ).slideDown(300, function () { $(this).animate({opacity: 1}, 300); });
		
		uploader.uploadButton.enable();
	};
	
	this.uploadStart = function (file) {
		uploader.queue[file.id].li.addClass("uploading").find(".status").html('').end().find(".cancel").remove();
	};
	
	this.uploadProgress = function (file, complete, total) {
	};
	
	this.uploadComplete = function(file) {
		uploader.queue[file.id].li.addClass("ready");
		if (uploader.status == "uploading") { uploader.startQueue(); }
		uploader.complete = uploader.complete + file.size;
	};
	
	this.uploadSuccess = function (file, respond) {
		uploader.queue[file.id].li.find(".status").html("Загружен");
		uploader.uploaded.push(respond);
	};
	
	this.uploadError = function (file, error, message) {
		if (typeof(uploader.queue[file.id]) != "undefined") {
			if (error != -280) {
				uploader.queue[file.id].li.addClass("error").find(".status").html("Ошибка: " + message);
			}
		};
		if (uploader.filesBox.find("li").length == 1) {
			uploader.uploadButton.disable();
		};		
	};
	
	this.selectFiles = function() {
		this.swf.selectFiles();
	};
	
	this.startQueue = function() {
		var next = uploader.filesBox.find("li:not(.ready)")[0];
		
		if (typeof(next) != "undefined") {
			uploader.status = "uploading";
			uploader.multiupload.find("#upload").hide().end().find(".addFile").hide();
			uploader.swf.startUpload(next.id);
		}
		else {
			var divider = ( uploader.url.indexOf("aspx?") == -1 ) ? "?" : "&";
			var _url = uploader.url + divider + "p=" + uploader.uploaded[0];
			for ( i = 1 ; i < uploader.uploaded.length; i++ )  {
				_url = _url +  "&p=" + uploader.uploaded[i];
			};
			uploader.afterStart.html('<a href="' + _url + '" id="nextButton" class="button">Дальше</a>');
		}
		return false;
	};
	
	
	
	options = $.extend(options, {
		swfupload_loaded_handler : function () { uploader.noflash = false; },
		file_queued_handler : this.fileQueued,
		upload_start_handler : this.uploadStart,
		upload_progress_handler : this.uploadProgress,
		upload_error_handler : this.uploadError,
		upload_success_handler : this.uploadSuccess,
		upload_complete_handler : this.uploadComplete
	});
	
	this.swf = new SWFUpload(options);
	
	setTimeout(function () {
		uploader.multiupload = uploaderbox.parents("form");
	
		uploader.uploadButton = uploader.multiupload.find("#upload");	
			
		uploader.uploadButton.enable = function () {
			uploader.uploadButton.removeAttr("disabled").removeClass("disabled");
		};
		uploader.uploadButton.disable = function () {
			uploader.uploadButton.attr("disabled","disabled").addClass("disabled");
		};		
				
		uploader.afterStart = $('<span class="afterStart"></span>').insertAfter(uploader.uploadButton).hide();;
		
		$("#upload").click( function () {
			uploader.uploadButton.hide();
			uploader.afterStart.html("Подождите, идет загрузка...").show();
			if (window.uploader.noflash) {			
				window.uploader.filesBox.find("li").addClass("uploading").find("a").remove();
			}
		});		
		
		if (!uploader.noflash) {
			uploader.uploadButton.disable();
			
			uploaderbox.hide();
				
			uploaderbox.after('<a class="addFile button" href="#">Добавить файл...</a><ul class="filesBox"></ul>');
			uploader.filesBox = $("#multiupload .filesBox");

			uploader.multiupload.find(".addFile").click( function () {
				uploader.selectFiles();
				return false;
			});
			uploader.multiupload.find("#upload").click( function () {
				uploader.startQueue();
				return false;
			});		
		}
		else {			
			uploaderbox.MultiFile({
				accept : 'gif|jpg|png',
				max : 5,
				STRING : {
					remove : '<a class="cancel" href="#"></a>',
					selected : "Файл: $file",
					denied : "Можно только картинки, а у вас $ext",
					duplicate : "Этот файл уже есть в очереди"
				}
			});
		};
	}, 200);

};

var uploader;
var uploaderbox;

$.fn.multiupload = function (options, url, gifpath) {
	if (typeof(url) == "undefined") { return false; }
	
	if (this.length > 0) {
		uploaderbox = $(this[0]);
		
		_loadingGif = gifpath || "http://static.dnevnik.ru/images/wait.gif";
		
		var opts = {
			flash_url : "http://static.dnevnik.ru/swf/swfupload.swf",
			file_size_limit : "4 MB",
			file_upload_limit : 100,
			file_queue_limit : 0,
			debug: false		
		};
		
		$.extend(opts, options);
		
		uploader = new Multiuploader(opts);
		window.uploader = uploader;
		uploader.url = url;
	};
	return this;
};
})(jQuery);